#pragma once
#include "kernel\feVector.h"
#include "kernel\feBordCond.h"
#include "kernel/fe1dParabolicTask.h"
#include "conductivelayer.h"
#include "kernel/feMeshFunction.h"

class TaskHelper
{
protected:
	feMesh *Mesh;

public:
	TaskHelper() {Mesh = 0; }
	virtual void SetMesh(feMesh *iMesh)  { Mesh = iMesh; }
	virtual double GetScaleSigma(int iLayerNum) { return 1; }
	virtual feVector * GetX0(bool iMainFieldCalc) = 0;
	virtual feMeshFunction * GetMfUFunction() = 0;
	virtual feMeshFunction * GetMfDuDtFunction() = 0;
	virtual double GetScaleFCoeff(int iLayerNum, double iSigma0) = 0;
	virtual bool Load() = 0;
	virtual feMeshFunction* GetRightFunction() = 0;
	virtual feBordCond ** GetBcs(bool iMainFieldCalc, int &oBcNum) = 0;
	virtual double GetStiffElemCoeff() { return 0; }
	virtual double GetWeightElemCoeff() { return 1; }
	virtual ~TaskHelper() {}
};


//---------------------------------------------------------------------------------------------------------------------
class XTaskHelper: public TaskHelper
{
	double	 M;
	double	 FirstTimeStep;
	int		 LayersTime;
	double	 TimeCoeff;
	feVector X0;
	feVector *UpBcVec;

// 	feSecondBordCond1d UpBc;
// 	feFirstBordCondVec1d DownBc;
	feFirstBordCond1d UpBc;
	feFirstBordCond1d DownBc;
	feBordCond *Bcs[2];
	ConductiveLayer	 *Layers;


	feSharedPtr<mfMesh>						MfMesh;
	feSharedPtr<feSimple1dMeshFunction>		MfUFunction;
	feSharedPtr<feSimple1dMeshFunction>		MfDuDtFunction;


public:
	void Init(ConductiveLayer *iLayers, double iM);
	virtual double GetScaleSigma(int iLayerNum);
	virtual feVector * GetX0(bool iMainFieldCalc);
	virtual feBordCond ** GetBcs(bool iMainFieldCalc, int &oBcNum);
	virtual feMeshFunction * GetMfUFunction();
	virtual feMeshFunction * GetMfDuDtFunction();
	virtual double GetStiffElemCoeff() { return 1; }
	virtual double GetWeightElemCoeff() { return M*M; }
	virtual double GetScaleFCoeff(int iLayerNum, double iSigma0);
	virtual bool Load();
	virtual feMeshFunction* GetRightFunction() { return static_cast<feMeshFunction*>((feSimple1dMeshFunction*)MfUFunction); }
	virtual ~XTaskHelper() {}

public:
	static bool CalcMainField();
};


//----------------------------------------------------------------------------------------------------------------------
class ZTaskHelper: public TaskHelper
{
	double	M;
	double	FirstTimeStep;
	int		LayersTime;
	double	TimeCoeff;
	feVector X0;

	feBordCond *Bcs[2];
	feThirdBordCond1d UpBc;
	feThirdBordCond1d DownBc;
	ConductiveLayer	  *Layers;


	feSharedPtr<mfMesh>						MfMesh;
	feSharedPtr<feSimple1dMeshFunction>		MfUFunction;
	feSharedPtr<feSimple1dMeshFunction>		MfDuDtFunction;


public:
	void Init(ConductiveLayer *iLayers, double iM);
	virtual feVector * GetX0(bool iMainFieldCalc);
	virtual feBordCond ** GetBcs(bool iMainFieldCalc, int &oBcNum);
	virtual feMeshFunction * GetMfUFunction();
	virtual feMeshFunction * GetMfDuDtFunction();
	virtual double GetScaleFCoeff(int iLayerNum, double iSigma0);
	virtual bool Load();
	virtual feMeshFunction * GetRightFunction() { return  static_cast<feMeshFunction*>((feSimple1dMeshFunction*)MfDuDtFunction); }
	virtual ~ZTaskHelper() {}

public:
	static bool CalcMainField();
};